package org.spring.bean.factory.config;

import org.spring.bean.exceptions.BeansException;

/**
 * 允许自定义修改应用上下文的工厂钩子Bean定义，调整上下文底层的Bean属性值bean工厂。
 * <p>
 * 适用于针对系统管理员的定制配置文件，这些配置文件覆盖了在应用程序上下文中配置的bean属性。
 * 参见{@link PropertyResourceConfigurer}及其具体的解决方案的开箱即用的实现，以满足这样的配置需求。
 * <p>
 * {@code BeanFactoryPostProcessor}可以与bean定义进行交互和修改，但不能与bean实例进行交互。
 * 这样做可能会导致bean过早实例化，违反容器并导致意想不到的副作用。如果需要bean实例交互，可以考虑实现{@link BeanPostProcessor}。
 * <p>
 * <h3>登记</h3>
 * 一个{@code ApplicationContext}在它的bean定义中自动检测{@code BeanFactoryPostProcessor} bean，并在创建任何其他bean之前应用它们。
 * 一个{@code BeanFactoryPostProcessor}也可以通过编程方式注册一个{@code ConfigurableApplicationContext}。
 * <p>
 * <h3>订购</h3>
 * 在{@code ApplicationContext}中被自动检测到的{@code BeanFactoryPostProcessor}的bean将根据
 * {@link PriorityOrdered}和{@link org.springframework.core.Ordered}语义。
 * 相比之下，{@code BeanFactoryPostProcessor}以编程方式注册{@code ConfigurableApplicationContext}的bean将按照注册的顺序被应用；
 * 任何通过实现{@code PriorityOrdered}或{@code Ordered}接口表达的排序语义都会被编程注册的后处理器忽略。
 * 此外，{@code BeanFactoryPostProcessor} bean不会考虑{@link org.spring.core.annotation.Order @Order}注释。
 *
 * @author 李坤
 * @date 2022/4/23 18:39
 */
public interface BeanFactoryPostProcessor {

    /**
     * 在标准初始化之后修改应用程序上下文的内部 bean 工厂。
     * 所有 bean 定义都将被加载，但还没有 bean 被实例化。这允许覆盖或添加属性，甚至是急切初始化的 bean。
     *
     * @param beanFactory 应用程序上下文使用的bean工厂
     *
     * @throws org.springframework.beans.BeansException 以防出现错误
     */
    void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}
